import { logger, eventBus } from '@/instance'
import { insertClip, moveClip } from '@/console/storyboard'
// import { Clip as IClip } from '@/types' // 待定
import { draggingTypeMap, eventsMap } from '@/constants'

import { Ref, ref, onMounted, onUnmounted } from 'vue'
import { Clip } from '@/core/clip'
import { Track } from '@/core/track'

export type DndComposition = {
  dragging: Ref<boolean>
  draggingType: Ref<draggingTypeMap>
  draggingOverIndex: Ref<number>
}

export function useDnd(storybord: Track): DndComposition {
  const dragging = ref(false)
  const draggingType = ref(draggingTypeMap.ADD_CLIP)
  const draggingOverIndex = ref(-1)
  const handleDragStart = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDragStart', e)
    dragging.value = true
    draggingType.value = draggingTypeMap.MOVE_CLIP
    e.e.dataTransfer!.dropEffect = 'move'
    e.e.dataTransfer!.effectAllowed = 'move'
    e.e.dataTransfer?.setData('text', e.data.id)
  }
  const handleDragEnd = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDragEnd', e)
    dragging.value = false
    draggingOverIndex.value = -1
  }
  const handleDragOver = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDragOver', e)
    e.e.dataTransfer!.dropEffect = 'move'
    e.e.dataTransfer!.effectAllowed = 'move'
    draggingOverIndex.value = storybord.clips.findIndex(
      (i) => i.id === e.data.id
    )
  }
  const handlePlaceHolderDragOver = (e: { e: Event; data: Clip }) => {
    logger.log('composables/storyboard', 'handlePlaceHolderDragOver', e)
    draggingOverIndex.value = storybord.clips.length
  }
  const handleDrop = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDrop', e)
    dragging.value = false
    const data = e.e.dataTransfer?.getData('text')
    switch (draggingType.value) {
      case draggingTypeMap.MOVE_CLIP:
        const index = storybord.clips.findIndex((i) => i.id === data)
        if (
          index !== draggingOverIndex.value &&
          index !== draggingOverIndex.value - 1
        ) {
          moveClip(storybord, index, draggingOverIndex.value)
        }
        break
      case draggingTypeMap.ADD_CLIP:
        insertClip(storybord, draggingOverIndex.value, JSON.parse(data!))
        break
    }
  }

  const handle3rdDragStart = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handle3rdDragStart', e)
    dragging.value = true
    draggingType.value = draggingTypeMap.ADD_CLIP
  }

  const handle3rdDragEnd = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handle3rdDragEnd', e)
    dragging.value = false
    draggingOverIndex.value = -1
  }

  const handleDragEnter = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDragEnter', e)
    dragging.value = true
  }

  const handleDragLeave = (e: { e: DragEvent; data: Clip }) => {
    logger.log('composables/storyboard', 'handleDragLeave', e)
    // dragging.value = false
  }

  onMounted(() => {
    eventBus.on(eventsMap.THIRD_DRAGSTART, handle3rdDragStart)
    eventBus.on(eventsMap.THIRD_DRAGEND, handle3rdDragEnd)
    eventBus.on('clip-dragstart', handleDragStart)
    eventBus.on('clip-dragend', handleDragEnd)
    eventBus.on('clip-dragover', handleDragOver)
    eventBus.on('clip-dragenter', handleDragEnter)
    eventBus.on('clip-dragleave', handleDragLeave)
    eventBus.on('placeholder-dragover', handlePlaceHolderDragOver)
    eventBus.on('clip-drop', handleDrop)
  })
  onUnmounted(() => {
    eventBus.off(eventsMap.THIRD_DRAGSTART, handle3rdDragStart)
    eventBus.off(eventsMap.THIRD_DRAGEND, handle3rdDragEnd)
    eventBus.off('clip-dragstart', handleDragStart)
    eventBus.off('clip-dragend', handleDragEnd)
    eventBus.off('clip-dragover', handleDragOver)
    eventBus.off('clip-dragenter', handleDragEnter)
    eventBus.off('clip-dragleave', handleDragLeave)
    eventBus.off('placeholder-dragover', handlePlaceHolderDragOver)
    eventBus.off('clip-drop', handleDrop)
  })
  return {
    dragging,
    draggingType,
    draggingOverIndex,
  }
}
